/*头文件引用*/
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/pid.h>
#include <linux/wait.h>
#include <linux/completion.h>
#include <linux/kthread.h>

MODULE_LICENSE("GPL");
/*全局变量定义*/
static struct completion comple;      //用于保存completion的状态
struct task_struct *old_thread;     //保存初始化进程的信息


int my_function(void * argc)
{
	wait_queue_head_t head;
	wait_queue_t data;
	printk("in the kernel thread function! \n");
	init_waitqueue_head(&head);                     //初始化等待队列头元素
	init_waitqueue_entry(&data, current);           //用当前进程初始化等待队列元素
	add_wait_queue(&head, &data);                   //将当前进程插入到等待队列中
	schedule_timeout_uninterruptible(10);           //将等待队列置于不可中断的等待状态
	printk("the current pid is:%d\n", current->pid);    //显示当前进程的PID值
	printk("the state of the real parent is :%ld\n", old_thread->state);
	//显示父进程的状态
	//complete(&comple);                            //调用函数唤醒进程并更改done字段的值
	printk("out the kernel thread function\n");
	return 0;
}

static int __init wait_for_completion_interruptible_timeout_init(void)
{
	struct task_struct * result;
	long leavetime;
	wait_queue_t data;
	printk("into wait_for_completion_interruptible_timeout_init.\n");
	old_thread = current;
	result=kthread_create_on_node(my_function, NULL, -1, "wait_for_interruptible_timeout");
	//创建新进程
	wake_up_process(result);
	/*获取新进程的描述符信息*/
	init_completion(&comple);                      //初始化completion变量
	init_waitqueue_entry(&data, result);           //用新进程初始化等待队列元素
	__add_wait_queue_tail(&(comple.wait), &data); // 将新进程加入等待队列的尾部
	leavetime=wait_for_completion_interruptible_timeout(&comple,1000);
	//阻塞进程等待新进程的结束
	/*显示函数wait_for_completion_interruptible_timeout( )的返回结果*/
	printk("the result of the wait_for_completion_interruptible_timeout is:%ld\n", leavetime);
	/*显示函数kernel_thread( )的返回结果*/
	printk("the pid of new thread is :%d\n", result->pid);
	printk("the current pid is:%d\n", current->pid);  //显示当前进程的PID值
	printk("out wait_for_completion_interruptible_timeout_init.\n");
	return 0;
}

static void __exit wait_for_completion_interruptible_timeout_exit(void)
{
printk("Goodbye wait_for_completion_interruptible_timeout\n");
}

module_init(wait_for_completion_interruptible_timeout_init);
module_exit(wait_for_completion_interruptible_timeout_exit);

